package org.gdstash.ui.table;

import javax.swing.*;
import javax.swing.table.TableRowSorter;
import java.util.Comparator;

public class GDItemSetCollectionSorter extends TableRowSorter<GDItemSetCollectionTableModel> {
    private static final int SORTORDER_DEFAULT = 0;
    private static final int SORTORDER_NAME = 1;
    private static final int SORTORDER_NAME_REV = 2;
    private static final int SORTORDER_LEVEL = 3;
    private static final int SORTORDER_LEVEL_REV = 4;
    private static final int SORTORDER_RARITY = 5;
    private static final int SORTORDER_RARITY_REV = 6;
    private static final Comparator<GDItemSetCollectionRow> COMP_NAME;
    private static final Comparator<GDItemSetCollectionRow> COMP_NAME_REV;
    private static final Comparator<GDItemSetCollectionRow> COMP_LEVEL;
    private static final Comparator<GDItemSetCollectionRow> COMP_LEVEL_REV;
    private static final Comparator<GDItemSetCollectionRow> COMP_RARITY;
    private static final Comparator<GDItemSetCollectionRow> COMP_RARITY_REV;
    private int sortOrder;

    public GDItemSetCollectionSorter() {
        this(null);
    }

    public GDItemSetCollectionSorter(final GDItemSetCollectionTableModel model) {
        this.setModel(model);
    }

    @Override
    public void setModel(final GDItemSetCollectionTableModel m) {
        super.setModel(m);
        if (m != null) {
            this.setSortable(0, false);
            this.sortOrder = 0;
        }
    }

    @Override
    public void toggleSortOrder(final int column) {
        if (column == 0) {
            if (this.sortOrder == 1) {
                this.sortOrder = 2;
            } else {
                this.sortOrder = 1;
            }
        }
        if (column == 1) {
            if (this.sortOrder == 3) {
                this.sortOrder = 4;
            } else {
                this.sortOrder = 3;
            }
        }
        if (column == 2) {
            if (this.sortOrder == 5) {
                this.sortOrder = 6;
            } else {
                this.sortOrder = 5;
            }
        }
    }

    static {
        COMP_NAME = new NameComparator();
        COMP_NAME_REV = new NameReverseComparator();
        COMP_LEVEL = new LevelComparator();
        COMP_LEVEL_REV = new LevelReverseComparator();
        COMP_RARITY = new RarityComparator();
        COMP_RARITY_REV = new RarityReverseComparator();
    }

    @Override
    public void sort() {
        final GDItemSetCollectionTableModel model = getModel();
        if (this.sortOrder == 1) {
            model.sort(GDItemSetCollectionSorter.COMP_NAME);
        }
        if (this.sortOrder == 2) {
            model.sort(GDItemSetCollectionSorter.COMP_NAME_REV);
        }
        if (this.sortOrder == 3) {
            model.sort(GDItemSetCollectionSorter.COMP_LEVEL);
        }
        if (this.sortOrder == 4) {
            model.sort(GDItemSetCollectionSorter.COMP_LEVEL_REV);
        }
        if (this.sortOrder == 5) {
            model.sort(GDItemSetCollectionSorter.COMP_RARITY);
        }
        if (this.sortOrder == 6) {
            model.sort(GDItemSetCollectionSorter.COMP_RARITY_REV);
        }
    }

    public static class NameComparator implements Comparator<GDItemSetCollectionRow> {
        @Override
        public int compare(final GDItemSetCollectionRow ir1, final GDItemSetCollectionRow ir2) {
            final int iName = ir1.setName.text.compareTo(ir2.setName.text);
            if (iName != 0) {
                return iName;
            }
            return ir1.level - ir2.level;
        }
    }

    private static class NameReverseComparator implements Comparator<GDItemSetCollectionRow> {
        @Override
        public int compare(final GDItemSetCollectionRow ir1, final GDItemSetCollectionRow ir2) {
            final int iName = ir1.setName.text.compareTo(ir2.setName.text);
            if (iName != 0) {
                return -iName;
            }
            return ir1.level - ir2.level;
        }
    }

    public static class LevelComparator implements Comparator<GDItemSetCollectionRow> {
        @Override
        public int compare(final GDItemSetCollectionRow ir1, final GDItemSetCollectionRow ir2) {
            final int iLevel = ir1.level - ir2.level;
            if (iLevel != 0) {
                return iLevel;
            }
            return ir1.setName.text.compareTo(ir2.setName.text);
        }
    }

    private static class LevelReverseComparator implements Comparator<GDItemSetCollectionRow> {
        @Override
        public int compare(final GDItemSetCollectionRow ir1, final GDItemSetCollectionRow ir2) {
            final int iLevel = ir1.level - ir2.level;
            if (iLevel != 0) {
                return -iLevel;
            }
            return ir1.setName.text.compareTo(ir2.setName.text);
        }
    }

    public static class RarityComparator implements Comparator<GDItemSetCollectionRow> {
        @Override
        public int compare(final GDItemSetCollectionRow ir1, final GDItemSetCollectionRow ir2) {
            final int iRarity = ir1.rarity - ir2.rarity;
            if (iRarity != 0) {
                return iRarity;
            }
            final int iName = ir1.setName.text.compareTo(ir2.setName.text);
            if (iName != 0) {
                return iName;
            }
            return ir1.level - ir2.level;
        }
    }

    private static class RarityReverseComparator implements Comparator<GDItemSetCollectionRow> {
        @Override
        public int compare(final GDItemSetCollectionRow ir1, final GDItemSetCollectionRow ir2) {
            final int iRarity = ir1.rarity - ir2.rarity;
            if (iRarity != 0) {
                return -iRarity;
            }
            final int iName = ir1.setName.text.compareTo(ir2.setName.text);
            if (iName != 0) {
                return iName;
            }
            return ir1.level - ir2.level;
        }
    }
}
